\chapter{前言}

\begin{flushright}
没有可以解决任何问题的编程技术\\
没有能只生成正确结果的编程语言\\
没有每个工程都从头开始的程序员\\
\end{flushright}


面向对象编程已经出现了十多年,它目前仍是解决问题的灵丹妙药。本质上,除了接 受了二十多年来的一
些好的编程法则外并没有什么新的东西带给我们。C++ 是一门新的语 言因为它是面向对象的,如果你不想使用或者不知道如何使用那么你不需要使用它,因为 普通的 C 就可以实现面向对象。虽然子程序的思想和计算机一样久远并且好的程序员总 是随身携带着他们的工具和库,但是只有面向对象才可以在不同项目间实现代码复用。

这本书不准备推崇面向对象或者批评传统的方式。我们准备以 ANSI-C 来发掘如何实 现面向对象,有哪些技术,为什么这些技术能帮我们解决更大的问题,如何利用它的一般 性以及更早的捕获异常。虽然我们会接触很多术语,如类、继承、实例、连接、方法、对 象、多态等等,但是我们将会剥去其魔幻的外表,使用我们熟悉的事物来表述他们。


我非常有意思的发现了 ANSI-C 其实是一门完全的面向对象的语言。如果想要和我分 享这份乐趣你需要非常熟悉它,至少也要对结构、指针、原型和函数指针。通过这本书, 你将遇到一个“新语言”——按照 Orwell 和韦氏词典对一门语言的解释,语言的设计目的 就是缩减思维的广度——而我会尽力证明,它不仅仅汇合了所有的那些你想汇聚到一起的 良好的编程原则。结果,你可以成为一个更熟练的 ANSI-C 程序员。


前六章建立 ANSI-C 做面向对象编程的基础。我们从一个抽象数据类型的信息隐藏技 术开始,然后加入基于动态连接的通用函数,再通过谨慎地扩充结构来继承代码。最后, 我们将上述所有放进一个类树中,来使代码更容易地维护。


编程需要规范。良好的编程更需要很多的规范、众多原则和标准以及确保正确无误的 防范措施。程序员使用工具,而优秀的程序员则制作工具来一劳永逸地处理那些重复的工 作。用 ANSI-C 的面向对象的编程需要相当大量的不变的代码——名称可能变化但结构不 变。因此,在第 7 章里我们搭建一个小小的预处理器,用来创建所需要的模板。它很像是 另一个方言式面向对象的语言。但是它不应该这样被看待,它剔除“方言”中枯燥无味的 东西,让我们专注于用更好的技术解决问题的创新。OOC 有非常好的可塑性:我们创造 了它,了解它,能够改变它,而且它可以如我们所愿的写 ANSI-C 代码。

￼余下章节继续深入讨论我们的技术。第 8 章加入动态类型检测来实现错误的早期捕 获。第 9 章讲我们通过使用自动初始化来防止另一类软件缺陷。第 10 章引入委托代理, 说明类和回调函数如何协作,比如去简化标准主程序的生成这样的常规任务。其他章节专 注于用类方法来堵塞内存泄漏,用一致的方法来存储和加载结构数据,和通过嵌套异常处 理系统的规范错误的恢复。

在最后一章,我们突破 ANSI-C 的限制,做了一个时髦的鼠标操作的计算器——先是 针对 curses 然后是针对 X Window 系统。这个例子极好地表明:即使是不得不应对外部 库和类树的风格,通过对象和类我们已然可以非常精致地进行设计和实现。

每一章都有总结,这些总结中我试图给随意浏览的读者一个梗概以及它对此后章节的 重要性。大多数的章节都有练习题,不过他们并不是正式的阐明性文字,因为我坚定的相 信读者应当自己实践。由于该技术是我们从无到有建立起来的,所以尽管有些例子应该能 够从中获益,但是我避免建立和使用庞大的类库。如果你想要真正地理解面向对象的编 程,首先掌握该技术并且在代码设计阶段考虑你的选择更为重要;而开发中依赖使用他人 的库应当在这稍后一点。

本书的一个重要部分是所附源码软盘2,——其上有一个 DOS 文件系统,包括一个用 来按照章节顺序来创建源码的简单 shell 脚本。还有一个 ReadMe 文件——在你执行 make 命令前要先查阅这个文件。使用一个工具如 diff 并且追踪根类和 OOC 报告在后续章节 的演化也是非常有帮助的。

这里展现的技术源自我对 C++ 的失望。当时我需要面向对象技术实现一个交互式 编程语言,但我意识到无法用 C++ 建立一个可移植的东西来。于是我转向我所了解的 ANSI-C,并且我完全能够做到要做的事情。我将这个些告诉组里的几个人,然后他们用同 样的方法完成了他们的工作。如果不是布赖恩 · 克尼翰(Brian Kernighan)以及我的出 版商翰斯 · 尼科拉斯(Hans-Joachim Niclas)、约翰 · 维特(John Wait)鼓励我出版这 些笔记(在适当的时候全新的展现一下),这个事情很可能就止于此,我的注解也就是一 时的时尚了。我感谢他们和所有帮助并且经历本书不断完善的人。最后但是并非不重要 的,感谢我的家庭——面向对象当然绝不可能代替餐桌上的面包。

1993 年 10 月于 Hollage

阿塞尔—托彼亚斯 · 斯莱内尔(Axel-Tobias Schreiner)